/*
 * Copyright 2011 Angel Sanadinov
 *
 * This file is part of VBox WMI.
 *
 * VBox WMI is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * VBox WMI is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with VBox WMI.  If not, see <http://www.gnu.org/licenses/>.
 */

package Managers.Utilities;

import java.sql.SQLException;
import Utilities.Constants;

/**
 * This class represents a result from the manipulation of the database by the database
 * manager.
 *
 * @author Angel Sanadinov
 */
public class DatabaseManipulationResult
{
    private boolean result;         //the result of the operation
    private SQLException exception; //reference to the expection, if one occured
    private int errorCode;          //an error code, if available

    /**
     * Constructs the object using only a boolean result.
     *
     * @param result the result of an operation
     */
    public DatabaseManipulationResult(boolean result)
    {
        this.result = result;
        this.errorCode = Constants.SQL_ERROR_UNKNOWN; //no error code available
    }

    /**
     * Constructs the object using a boolean result and an exception object.
     *
     * @param result the result of an operation
     * @param exception the exception that occurred why performing the operation
     */
    public DatabaseManipulationResult(boolean result, SQLException exception)
    {
        this.result = result;
        this.exception = exception;
        this.errorCode = Constants.SQL_ERROR_UNKNOWN;
    }

    /**
     * Constructs the object using a boolean result and a custom error code. <br><br>
     *
     * <b>Note:</b> <i>The error code used by this class is not associated with
     *              the SQL error codes used by specific databases.</i>
     *
     * @param result the result of an operation
     * @param errorCode a custom error code associated with the result of the operation
     *
     * @see Constants SQL Result Codes
     */
    public DatabaseManipulationResult(boolean result, int errorCode)
    {
        this.result = result;
        this.errorCode = errorCode;
    }

    /**
     * Retrieves the result of the database operation.
     *
     * @return <code>true</code> if the operation was successful or <code>false</code>
     *         otherwise
     */
    public boolean wasOperationSuccessful()
    {
        return result;
    }

    /**
     * Retrieves the exception object associated with this database operation result.
     *
     * @return the exception object
     */
    public SQLException getException()
    {
        return exception;
    }

    /**
     * Retrieves the error code associated with this database operation result. <br><br>
     *
     * <b>Note:</b> <i>This error code is not associated with the SQL error codes
     *              used by specific databases. Those codes can be retrieved by using
     *              the <code>getErrorCode()</code> of the exception object, if one
     *              is available.</i>
     *
     * @return the custom error code associated with this result
     *
     * @see Constants Custom Error Codes
     * @see SQLException#getErrorCode() 
     */
    public int getErrorCode()
    {
        //checks if an exception is available
        if(exception != null)
            return parseSQLState(exception.getSQLState());//converts the sql state to error code
        else
            return errorCode;
    }

    /**
     * Parses the specified SQL State and return the associated custom error code.
     *
     * @param state the SQL state
     *
     * @return the error code associated with the specified SQL state or
     *         <code>Constants.SQL_ERROR_UNKNOW</code> if a specific error code
     *         could not be determined
     *
     * @see Constants
     * @see Constants#SQL_ERROR_UNKNOWN
     */
    private int parseSQLState(String state)
    {
        int parsedState = Constants.SQL_NO_ERROR;

        switch(Integer.parseInt(state))
        {
            case 23000: parsedState = Constants.SQL_ERROR_ENTRY_EXISTS; break;

            default: parsedState = Constants.SQL_ERROR_UNKNOWN; break;
        }

        return parsedState;
    }
}
